//
// Created by Administrator on 2019/6/6 0006.
//

#include "JavaCallback.h"
#include "macro.h"

JavaCallback::JavaCallback(JavaVM *_javaVM, JNIEnv *_env, jobject &_jobj) : javaVM(_javaVM), env(_env) {
//    this->javaVM = _javaVM;
//    this->env = _env;

    //创建一个jobject对象，不能直接赋值(this->jobj = _jobj)
    //todo 一旦涉及到jobject跨方法、跨线程，需要建全局引用
    jobj = env->NewGlobalRef(_jobj);
    jclass jclazz = env->GetObjectClass(jobj);
    //int I, short s, byte b, boolean z, double D, long L, char C
    //应用类型 L+包名+类名
    //todo 参数三解释：(I)表示onError方法参数的类型为int，V表示返回值为void
    jmid_error = env->GetMethodID(jclazz, "onError", "(I)V");
    //todo 参数三解释：()表示onPrepare方法没有参数，V表示返回值为void
    jmid_prepare = env->GetMethodID(jclazz, "onPrepare", "()V");
    //todo 参数三解释：(I)表示onProgress方法参数的类型为int，V表示返回值为void
    jmid_progress = env->GetMethodID(jclazz, "onProgress", "(I)V");
}

JavaCallback::~JavaCallback() {
    javaVM = 0;
    env->DeleteGlobalRef(jobj);
    jobj = 0;
}

void JavaCallback::onError(int thread, int code) {
    if (thread == THREAD_CHILD) {
        //绑定主线程
        JNIEnv *jniEnv;
        if (javaVM->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
            return;
        }
        jniEnv->CallVoidMethod(jobj, jmid_error, code);
        javaVM->DetachCurrentThread();
    } else {
        env->CallVoidMethod(jobj, jmid_error, code);
    }
}

void JavaCallback::onPrepare(int thread) {
    if (thread == THREAD_CHILD) {
        //绑定主线程，拿到当前子线程的JNIEnv
        JNIEnv *jniEnv;
        //创建 JNIEnv , 每一个线程创建一个
        if (javaVM->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
            return;
        }
        jniEnv->CallVoidMethod(jobj, jmid_prepare);
        //释放本线程的 JNIEnv
        javaVM->DetachCurrentThread();
    } else {
        env->CallVoidMethod(jobj, jmid_prepare);
    }
}

void JavaCallback::onProgress(int thread, int progress) {
    if (thread == THREAD_CHILD) {
        //绑定主线程
        JNIEnv *jniEnv;
        if (javaVM->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
            return;
        }
        jniEnv->CallVoidMethod(jobj, jmid_progress, progress);
        javaVM->DetachCurrentThread();
    } else {
        env->CallVoidMethod(jobj, jmid_progress, progress);
    }
}
